/*
 * VentanaCache.java
 *
 * Created on 4 de octubre de 2008, 10:46
 */

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.io.File;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;

/**
 *
 * @author Juan Pablo
 */
public class VentanaCache extends javax.swing.JFrame {
	//atributos de clase
	private ControladorRC controlador;
	private Modelo modelo;
	private JTable cache;
	private String[] nombre;
	private JLabel[] lineaReemplazada;
	private ModeloColor color;
	private File verificar;
	/**
	 * crear la ventana
	 */
	public VentanaCache() {
		initComponents();
		setExtendedState(MAXIMIZED_BOTH);//maximizar
		// verificar Ram
		try{
		verificar=new File("RAM.txt");
		System.out.println("El archivo ram existe");
		} catch(Exception e){
			//revisar
			JOptionPane.showMessageDialog(null, "No se reconocio el archivo RAM.txt, se creara uno automaticamente");
			controlador.crearRam();
		}
		verificar=null;

		// crear jtable vacia
		controlador = new ControladorRC();
		nombre = new String[] { "Tag", "Dato", "Dato", "Dato", "Dato" };
		modelo = new Modelo(controlador.getMemoria(), nombre);
		cache = new JTable(modelo);
		cache.getTableHeader().setReorderingAllowed(false);
		JScrollPane scroll = new JScrollPane(cache);
		acomodador.add(scroll, BorderLayout.CENTER);
		crearRam.setVisible(false);
		reemplazada.setLayout(new GridLayout(1, 5, 40, 20));
		// arreglo de jlabels para la linea reemplazada
		lineaReemplazada = new JLabel[5];
		if (ConjuntoCache.reemplazada() != null) {
			for (int i = 0; i < lineaReemplazada.length; i++) {
				lineaReemplazada[i] = new JLabel(""
						+ ConjuntoCache.reemplazada().getLinea()[i]);
			}
		} else {
			for (int i = 0; i < lineaReemplazada.length; i++) {
				lineaReemplazada[i] = new JLabel("   ");
			}
		}
		for (int i = 0; i < lineaReemplazada.length; i++) {
			reemplazada.add(lineaReemplazada[i]);
		}
	}

	/**
	 * metodo generado para la interfaz grafica
	 */
	@SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed" desc="Generated
	// Code">//GEN-BEGIN:initComponents
	private void initComponents() {

		scrollGlobal = new javax.swing.JScrollPane();
		panelGlobal = new javax.swing.JPanel();
		panelCache = new javax.swing.JPanel();
		acomodador = new javax.swing.JPanel();
		reemplazada = new javax.swing.JPanel();
		contenedor = new javax.swing.JPanel();
		panelOpciones = new javax.swing.JPanel();
		crearRam = new javax.swing.JButton();
		direccionParaCache = new javax.swing.JTextField();
		labelDireccionCache = new javax.swing.JLabel();
		pedirDato = new javax.swing.JButton();
		panelRam = new javax.swing.JPanel();
		direccion = new javax.swing.JTextField();
		dato = new javax.swing.JTextField();
		labelDireccion = new javax.swing.JLabel();
		labelDato = new javax.swing.JLabel();
		direccionar = new javax.swing.JButton();
		estado = new javax.swing.JLabel();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle("Simulador de CACHE");

		panelCache.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Memoria CACHE"));

		acomodador.setLayout(new java.awt.BorderLayout());

		reemplazada.setBorder(javax.swing.BorderFactory.createTitledBorder(
				null, "Linea Reemplazada",
				javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
				javax.swing.border.TitledBorder.DEFAULT_POSITION,
				new java.awt.Font("Tahoma", 0, 11), java.awt.Color.black)); // NOI18N

		javax.swing.GroupLayout reemplazadaLayout = new javax.swing.GroupLayout(
				reemplazada);
		reemplazada.setLayout(reemplazadaLayout);
		reemplazadaLayout.setHorizontalGroup(reemplazadaLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGap(0, 441, Short.MAX_VALUE));
		reemplazadaLayout.setVerticalGroup(reemplazadaLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGap(0, 51, Short.MAX_VALUE));

		javax.swing.GroupLayout panelCacheLayout = new javax.swing.GroupLayout(
				panelCache);
		panelCache.setLayout(panelCacheLayout);
		panelCacheLayout.setHorizontalGroup(panelCacheLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addComponent(reemplazada,
						javax.swing.GroupLayout.Alignment.TRAILING,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
				.addComponent(acomodador, javax.swing.GroupLayout.DEFAULT_SIZE,
						457, Short.MAX_VALUE));
		panelCacheLayout.setVerticalGroup(panelCacheLayout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGroup(
				javax.swing.GroupLayout.Alignment.TRAILING,
				panelCacheLayout.createSequentialGroup().addComponent(
						acomodador, javax.swing.GroupLayout.DEFAULT_SIZE, 407,
						Short.MAX_VALUE).addPreferredGap(
						javax.swing.LayoutStyle.ComponentPlacement.RELATED)
						.addComponent(reemplazada,
								javax.swing.GroupLayout.PREFERRED_SIZE,
								javax.swing.GroupLayout.DEFAULT_SIZE,
								javax.swing.GroupLayout.PREFERRED_SIZE)));

		contenedor.setLayout(new java.awt.GridLayout(2, 1));

		panelOpciones.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Opciones"));

		crearRam.setText("Crear la RAM");
		crearRam.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				crearRamActionPerformed(evt);
			}
		});

		labelDireccionCache.setText("Direccion:");

		pedirDato.setText("Pedir Dato");
		pedirDato.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				pedirDatoActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout panelOpcionesLayout = new javax.swing.GroupLayout(
				panelOpciones);
		panelOpciones.setLayout(panelOpcionesLayout);
		panelOpcionesLayout
				.setHorizontalGroup(panelOpcionesLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								panelOpcionesLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												panelOpcionesLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																crearRam,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																131,
																Short.MAX_VALUE)
														.addComponent(
																direccionParaCache,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																131,
																Short.MAX_VALUE)
														.addComponent(
																labelDireccionCache,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																131,
																Short.MAX_VALUE)
														.addComponent(
																pedirDato,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																131,
																Short.MAX_VALUE))
										.addContainerGap()));
		panelOpcionesLayout
				.setVerticalGroup(panelOpcionesLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								panelOpcionesLayout
										.createSequentialGroup()
										.addComponent(crearRam)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(labelDireccionCache)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												direccionParaCache,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(pedirDato)
										.addContainerGap(134, Short.MAX_VALUE)));

		contenedor.add(panelOpciones);

		panelRam.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Escribir Memoria"));

		labelDireccion.setText("Direccion:");

		labelDato.setText("Dato:");

		direccionar.setText("Direccionar");
		direccionar.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				direccionarActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout panelRamLayout = new javax.swing.GroupLayout(
				panelRam);
		panelRam.setLayout(panelRamLayout);
		panelRamLayout
				.setHorizontalGroup(panelRamLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								javax.swing.GroupLayout.Alignment.TRAILING,
								panelRamLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												panelRamLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING)
														.addComponent(
																estado,
																javax.swing.GroupLayout.Alignment.LEADING,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																131,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																direccion,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																131,
																Short.MAX_VALUE)
														.addComponent(
																dato,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																131,
																Short.MAX_VALUE)
														.addComponent(
																labelDireccion,
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																labelDato,
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																direccionar,
																javax.swing.GroupLayout.Alignment.LEADING,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																131,
																Short.MAX_VALUE))
										.addContainerGap()));
		panelRamLayout
				.setVerticalGroup(panelRamLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								panelRamLayout
										.createSequentialGroup()
										.addComponent(labelDireccion)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												direccion,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(labelDato)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												dato,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(direccionar)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												estado,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												100, Short.MAX_VALUE)
										.addContainerGap()));

		contenedor.add(panelRam);

		javax.swing.GroupLayout panelGlobalLayout = new javax.swing.GroupLayout(
				panelGlobal);
		panelGlobal.setLayout(panelGlobalLayout);
		panelGlobalLayout
				.setHorizontalGroup(panelGlobalLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								javax.swing.GroupLayout.Alignment.TRAILING,
								panelGlobalLayout
										.createSequentialGroup()
										.addContainerGap()
										.addComponent(
												panelCache,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
										.addComponent(
												contenedor,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												167,
												javax.swing.GroupLayout.PREFERRED_SIZE)));
		panelGlobalLayout
				.setVerticalGroup(panelGlobalLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								javax.swing.GroupLayout.Alignment.TRAILING,
								panelGlobalLayout
										.createSequentialGroup()
										.addGroup(
												panelGlobalLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING)
														.addComponent(
																panelCache,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																Short.MAX_VALUE)
														.addComponent(
																contenedor,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																524,
																Short.MAX_VALUE))
										.addContainerGap()));

		scrollGlobal.setViewportView(panelGlobal);

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addComponent(
				scrollGlobal, javax.swing.GroupLayout.DEFAULT_SIZE, 678,
				Short.MAX_VALUE));
		layout.setVerticalGroup(layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addComponent(
				scrollGlobal, javax.swing.GroupLayout.DEFAULT_SIZE, 548,
				Short.MAX_VALUE));

		pack();
	}// </editor-fold>//GEN-END:initComponents

	private void crearRamActionPerformed(java.awt.event.ActionEvent evt) {
		// accion para crear ram, no implementado
	}
	/**
	 * accion para hacer una peticion de un dato a memoria
	 * @param evt
	 */
	private void pedirDatoActionPerformed(java.awt.event.ActionEvent evt) {
		try {
			//validacion
			if (Integer.parseInt(direccionParaCache.getText()) >= 0
					&& Integer.parseInt(direccionParaCache.getText()) <= 2048) {
				boolean acierto = controlador.peticion(Integer
						.parseInt(direccionParaCache.getText()));
				if (acierto) {//si hubo acierto de cache
					estado.setText("<HTML>Estado: Acierto de la Cache</HTML>");
					//pintar loscolores de la jtable por si fueron actualizados
					color=new ModeloColor();
					color.setActualizadas(controlador.getActualizados());
					cache.setDefaultRenderer(Object.class, color);
					cache.repaint();
				} else {//si no hubo acierto de cache
					//formulas para el calculo del conjunto y linea
					int conjunto = Utilidades.calcularGrupo(Integer
							.parseInt(direccionParaCache.getText()));
					int lineaCache = 4
							* conjunto + controlador.getIndice(conjunto)-1;
					if(lineaCache==-1)
						lineaCache=3;
					estado
							.setText("<HTML>Estado: Fallo de Cache, traido al Conjunto "
									+ conjunto
									+ "<HTML> y linea "
									+ lineaCache+"</HTML>");
					//actualizar la jtable para visualizar los datos
					modelo = new Modelo(controlador.getMemoria(),
							nombre);
					cache.setModel(modelo);
					//asignar el color
					color=new ModeloColor();
					color.setActualizadas(controlador.getActualizados());
					cache.setDefaultRenderer(Object.class, color);
					// crear la linea reemplazada
					if (ConjuntoCache.reemplazada() != null) {
						for (int i = 0; i < lineaReemplazada.length; i++) {
							lineaReemplazada[i]
									.setText(""
											+ ConjuntoCache.reemplazada()
													.getLinea()[i]);
						}
					} else {
						for (int i = 0; i < lineaReemplazada.length; i++) {
							lineaReemplazada[i].setText("   ");
						}
					}
				}
			} else {
				estado
						.setText("<HTML>Estado: La direccion no es valida</HTML>");
			}
		} catch (Exception e) {
			estado.setText("<HTML>Estado: Dato no valido</HTML>");
		}
	}
	/**
	 * accion para direccionar un dato
	 * @param evt
	 */
	private void direccionarActionPerformed(java.awt.event.ActionEvent evt) {
		try {
			if (Integer.parseInt(direccion.getText()) >= 0
					&& Integer.parseInt(direccion.getText()) <= 2048) {
				if (Integer.parseInt(dato.getText()) >= 0
						&& Integer.parseInt(dato.getText()) <= 255) {
					controlador.escribirEnRam(Integer.parseInt(direccion
							.getText()), Integer.parseInt(dato.getText()));
					estado
							.setText("<HTML>Estado: Dato escrito en RAM o en Cache y actualizado si fue necesario</HTML>");
					modelo = new Modelo(controlador.getMemoria(),
							nombre);
					cache.setModel(modelo);
					color=new ModeloColor();
					color.setActualizadas(controlador.getActualizados());
					cache.setDefaultRenderer(Object.class, color);
				} else {
					estado
							.setText("<HTML>Estado: Por favor ingrese un entero entre 0 y 255");
				}
			} else {
				estado.setText("<HTML>Estado: Direccion no valida</HTML>");
			}
		} catch (Exception e) {
			estado.setText("<HTML>Estado: Datos no validos</HTML>");
		}
	}

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		try {
			// UIManager
			// .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
		} catch (Exception e) {
		}
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				new VentanaCache().setVisible(true);
			}
		});
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JPanel acomodador;
	private javax.swing.JPanel contenedor;
	private javax.swing.JButton crearRam;
	private javax.swing.JTextField dato;
	private javax.swing.JTextField direccion;
	private javax.swing.JTextField direccionParaCache;
	private javax.swing.JButton direccionar;
	private javax.swing.JLabel estado;
	private javax.swing.JLabel labelDato;
	private javax.swing.JLabel labelDireccion;
	private javax.swing.JLabel labelDireccionCache;
	private javax.swing.JPanel panelCache;
	private javax.swing.JPanel panelGlobal;
	private javax.swing.JPanel panelOpciones;
	private javax.swing.JPanel panelRam;
	private javax.swing.JButton pedirDato;
	private javax.swing.JPanel reemplazada;
	private javax.swing.JScrollPane scrollGlobal;
	// End of variables declaration//GEN-END:variables
}
